package com.alibaba.citrus.ots.sales.plan.facade.service.salesplan.report;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.sales.plan.api.salesplan.report.SalesPlanReportQueryService;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanAuditRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanReportRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanAuditTaskQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanReportPageQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanReportQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanReportRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.response.SalesPlanAuditRecordResponse;
import com.alibaba.citrus.ots.sales.plan.model.SalesPlanReportAuditStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.SalesPlanReportBizTypeEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.AuditOperateTypeEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.FeaturesKeyEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalePlanAuditStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesPlanModelEnum;
import com.alibaba.citrus.ots.sales.plan.repository.PlatformEnhanceRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanAuditRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanAuditTaskRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanReportRepository;
import com.alibaba.citrus.ots.sales.plan.repository.request.OrganizationListQueryRequest;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanAuditSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanAuditTaskSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanReportSDO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.auditsetting.model.AuditSetting;
import com.epoch.app.bcots.auditsetting.service.AuditSettingService;
import com.epoch.app.bcots.auditsettingdetail.model.AuditSettingDetail;
import com.epoch.app.bcots.auditsettingdetail.service.AuditSettingDetailService;
import com.epoch.app.bcots.contants.BcOtsConstants;
import com.epoch.app.bcots.model.dto.AuditSettingDetailLoadListRequest;
import com.epoch.app.bcots.model.dto.AuditSettingLoadListRequest;
import com.epoch.app.bcots.model.dto.GetAllRolesRequest;
import com.epoch.app.bcots.model.dto.RoleSDO;
import com.epoch.app.bcots.model.enums.AuditSettingStatusEnum;
import com.epoch.app.bcots.model.enums.AuditSettingTypeEnum;
import com.epoch.app.bcots.service.BcOtsService;
import com.epoch.app.otsplatformenhance.enums.OrganizationTypeEnum;
import com.epoch.app.otsplatformenhance.sdo.EmployeeSDO;
import com.epoch.app.otsplatformenhance.sdo.OrganizationSDO;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class SalesPlanReportQueryServiceImpl implements SalesPlanReportQueryService {

    private final Log log = Log.getLogger(SalesPlanReportQueryServiceImpl.class);
    @Resource
    private SalesPlanReportRepository salesPlanReportRepository;

    @Resource
    private SalesPlanAuditTaskRepository salesPlanAuditTaskRepository;

    @Resource
    private SalesPlanAuditRepository salesPlanAuditRepository;

    @Resource
    private PlatformEnhanceRepository platformEnhanceRepository;

    @Resource(name = "auditSettingServiceImpl")
    private AuditSettingService auditSettingService;


    @Resource(name = "auditSettingDetailServiceImpl")
    private AuditSettingDetailService auditSettingDetailService;

    @Resource
    private BcOtsService bcOtsService;

    private final static String USER_PREFIX = "CZ_";

    private final static String SALES_PLAN_REPORT_SWITCH = "TRUE";

    @Override
    @FacadeInvoker
    public Result<PageResult<List<SalesPlanReportSDO>>> pageQuerySalesPlanReport(SalesPlanReportPageQueryRequest request) {
        return Result.success(salesPlanReportRepository.pageQuery(request));
    }

    @Override
    @FacadeInvoker
    public Result<SalesPlanReportSDO> querySalesPlanReport(SalesPlanReportQueryRequest request) {
        SalesPlanReportPageQueryRequest pageQueryRequest = convertSalesPlanReportPageQueryRequest(request);
        pageQueryRequest.setStart(0);
        pageQueryRequest.setLimit(1);
        PageResult<List<SalesPlanReportSDO>> pageResult = salesPlanReportRepository.pageQuery(pageQueryRequest);
        if (null != pageResult && pageResult.getTotal() > 0) {
            return Result.success(pageResult.getContent().get(0));
        }
        return Result.success(null) ;
    }

    /**
     * 查询前序提报单集审批状态
     * 前序提报单是否都审批通过
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<Boolean> queryPreSalesPlanReportAuditStatus(SalesPlanReportRequest request) {
        SalesPlanReportQueryRequest reportQueryRequest = new SalesPlanReportQueryRequest();
        // 构建提报维度
        boolean reportDimension = buildSalesPlanReportDimension(reportQueryRequest, request);
        if (!reportDimension) {
            return Result.success(reportDimension);
        }
        // 构建提报查询
        buildReportQueryRequest(reportQueryRequest, request);
        // 获取前序提报单
        return Result.success(fetchPreReportAuditStatus(reportQueryRequest,request));
    }

    /**
     * 查询提报单对应的审批记录
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<List<SalesPlanAuditRecordResponse>> querySalesPlanAuditRecordList(SalesPlanReportRequest request) {
        if (null == request || StringUtils.isBlank(request.getReportOrderId())) {
            return Result.success(Lists.newArrayList());
        }
        // 获取提报单下所有的审批单
        List<SalesPlanAuditSDO> salesPlanAuditSDOList = querySalesPlanAuditList(request);
        if (CollectionUtils.isEmpty(salesPlanAuditSDOList)) {
            return Result.success(Lists.newArrayList());
        }
        // 获取所有的审批任务
        List<String> auditIdList = salesPlanAuditSDOList.stream().map(SalesPlanAuditSDO::getId).collect(Collectors.toList());
        List<SalesPlanAuditTaskSDO> salesPlanAuditTaskSDOList = querySalesPlanAuditTaskList(auditIdList);
        if (CollectionUtils.isEmpty(salesPlanAuditTaskSDOList)) {
            return Result.success(Lists.newArrayList());
        }
        return Result.success(refreshSalesPlanAuditRecord(salesPlanAuditSDOList, salesPlanAuditTaskSDOList));
    }

    /**
     * 查询当前操作人对应的提报单是否有审批权限
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<Boolean> verifyAuditPermission(SalesPlanReportRequest request) {
        // 参数检查
        if (!checkParam(request)) {
            return Result.success(false);
        }
        // 查询审批单
        SalesPlanReportSDO salesPlanReportSDO = fetchSalesPlanReportSDO(request.getReportOrderId());
        if (null == salesPlanReportSDO) {
            return Result.success(false);
        }
        if (SalesPlanReportAuditStatusEnum.UNDER_REVIEW.getCode() != salesPlanReportSDO.getAuditStatus()) {
            return Result.success(false);
        }
        // 校验审批人
        if (null == salesPlanReportSDO.getFeatures()) {
            return Result.success(false);
        }
        JSONObject jsonObject = JSONObject.parseObject(salesPlanReportSDO.getFeatures());
        if (StringUtils.isBlank(jsonObject.getString(FeaturesKeyEnum.TASK_CODE.getName()))) {
            return Result.success(false);
        }
        SalesPlanAuditTaskSDO salesPlanAuditTaskSDO = fetchSalesPlanAuditTaskSDO(jsonObject.getString(FeaturesKeyEnum.TASK_CODE.getName()));
        if (null == salesPlanAuditTaskSDO) {
            return Result.success(false);
        }
        if (null != salesPlanAuditTaskSDO.getAssignees() && salesPlanAuditTaskSDO.getAssignees().lastIndexOf(request.getOperatorId()) > -1) {
            return Result.success(true);
        }
        return Result.success(false);
    }

    /**
     * 批量验证审批权限
     * Map<String, Boolean>  key是提报单id，value是是否有审核权限
     *
     * @param request
     * @return
     */
    @Override
    public Result<Map<String, Boolean>> batchVerifyAuditPermission(SalesPlanReportRequest request) {
        // 参数校验
        if (!checkBatchVerifyAuditPermissionParam(request)) {
            return Result.success(Maps.newHashMap());
        }
        List<SalesPlanReportSDO> salesPlanReportSDOList = batchFetchSalesPlanReportSDO(request);
        if (CollectionUtils.isEmpty(salesPlanReportSDOList)) {
            return Result.success(Maps.newHashMap());
        }
        List<String> taskCodeList = Lists.newArrayList();
        Map<String, String> reportRelationMap = Maps.newHashMap();
        salesPlanReportSDOList.forEach(salesPlanReportSDO -> {
            if (SalesPlanReportAuditStatusEnum.UNDER_REVIEW.getCode() != salesPlanReportSDO.getAuditStatus()) {
                return;
            }
            // 校验审批人
            if (null == salesPlanReportSDO.getFeatures()) {
                return;
            }
            JSONObject jsonObject = JSONObject.parseObject(salesPlanReportSDO.getFeatures());
            String taskCode = jsonObject.getString(FeaturesKeyEnum.TASK_CODE.getName());
            if (StringUtils.isBlank(taskCode)) {
                return;
            }
            taskCodeList.add(taskCode);
            reportRelationMap.put(taskCode, salesPlanReportSDO.getId());
        });
        List<SalesPlanAuditTaskSDO> planAuditTaskSDOList = batchFetchSalesPlanAuditTaskSDO(taskCodeList);
        if (CollectionUtils.isEmpty(planAuditTaskSDOList)) {
            return Result.success(Maps.newHashMap());
        }
        Map<String , Boolean> auditMap = Maps.newHashMap();
        planAuditTaskSDOList.forEach(taskSDO -> {
            if (null == taskSDO.getAssignees() || taskSDO.getAssignees().lastIndexOf(request.getOperatorId()) < 0) {
                return;
            }
            if (null != reportRelationMap.get(taskSDO.getTaskCode())) {
                auditMap.put(reportRelationMap.get(taskSDO.getTaskCode()), true);
            }
        });
        return Result.success(auditMap);
    }

    private List<SalesPlanReportSDO> batchFetchSalesPlanReportSDO(SalesPlanReportRequest request) {
        SalesPlanReportPageQueryRequest pageQueryRequest = new SalesPlanReportPageQueryRequest();
        pageQueryRequest.setStart(0);
        pageQueryRequest.setLimit(200);
        pageQueryRequest.setReportIdList(request.getReportOrderIdList().stream().map(Long::parseLong).collect(Collectors.toList()));
        PageResult<List<SalesPlanReportSDO>> pageResult = salesPlanReportRepository.pageQuery(pageQueryRequest);
        if (null == pageResult || pageResult.getTotal() < 1) {
            return null;
        }
        return pageResult.getContent();
    }

    private List<SalesPlanAuditTaskSDO> batchFetchSalesPlanAuditTaskSDO(List<String> taskCodeList) {
        if (CollectionUtils.isEmpty(taskCodeList)) {
            return null;
        }
        SalesPlanAuditTaskQueryRequest request = new SalesPlanAuditTaskQueryRequest();
        request.setTaskCodeList(taskCodeList);
        request.setStart(0);
        request.setLimit(200);
        PageResult<List<SalesPlanAuditTaskSDO>> pageResult = salesPlanAuditTaskRepository.pageQuery(request);
        if (null == pageResult || pageResult.getTotal() < 1) {
            return null;
        }
        return pageResult.getContent();
    }

    private boolean checkBatchVerifyAuditPermissionParam(SalesPlanReportRequest request) {
        if (null == request) {
            return false;
        }
        if (CollectionUtils.isEmpty(request.getReportOrderIdList())) {
            return false;
        }
        return !StringUtils.isBlank(request.getOperatorId());
    }

    private SalesPlanAuditTaskSDO fetchSalesPlanAuditTaskSDO(String taskCode) {
        SalesPlanAuditTaskQueryRequest request = new SalesPlanAuditTaskQueryRequest();
        request.setTaskCode(taskCode);
        request.setStart(0);
        request.setLimit(1);
        PageResult<List<SalesPlanAuditTaskSDO>> pageResult = salesPlanAuditTaskRepository.pageQuery(request);
        if (null == pageResult || pageResult.getTotal() < 1) {
            return null;
        }
        return pageResult.getContent().get(0);
    }

    private SalesPlanReportSDO fetchSalesPlanReportSDO(String reportId) {
        QuerySalesPlanReportRequest request = new QuerySalesPlanReportRequest();
        request.setId(reportId);
        return salesPlanReportRepository.load(request);
    }

    private boolean checkParam(SalesPlanReportRequest request) {
        if (null == request) {
            return false;
        }
        if (StringUtils.isBlank(request.getReportOrderId())) {
            return false;
        }
        return !StringUtils.isBlank(request.getOperatorId());
    }

    private List<SalesPlanAuditRecordResponse> refreshSalesPlanAuditRecord(List<SalesPlanAuditSDO> salesPlanAuditSDOList, List<SalesPlanAuditTaskSDO> salesPlanAuditTaskSDOList) {
        Map<String, String> operateNameMap = fetchOperatorName(salesPlanAuditTaskSDOList);
        Map<String, SalesPlanAuditSDO> auditSDOMap = salesPlanAuditSDOList.stream().collect(Collectors.toMap(SalesPlanAuditSDO::getId, Function.identity()));
        List<SalesPlanAuditRecordResponse> salesPlanAuditRecordResponseList = Lists.newArrayList();
        salesPlanAuditTaskSDOList.forEach(taskSDO -> {
            salesPlanAuditRecordResponseList.addAll(refreshSalesPlanAuditRecordResponse(taskSDO, operateNameMap, auditSDOMap.get(taskSDO.getAuditOrderId())));
        });
        return salesPlanAuditRecordResponseList;
    }

    private List<SalesPlanAuditRecordResponse> refreshSalesPlanAuditRecordResponse(SalesPlanAuditTaskSDO taskSDO, Map<String, String> operateNameMap, SalesPlanAuditSDO auditSDO) {
        List<SalesPlanAuditRecordResponse> recordResponses = Lists.newArrayList();
        SalesPlanAuditRecordResponse response;
        // 发起人
        if (StringUtils.isNotBlank(taskSDO.getAuditInitiatorId())) {
            response = new SalesPlanAuditRecordResponse();
            response.setOperatorName(operateNameMap.get(taskSDO.getAuditInitiatorId().replace(USER_PREFIX, "")));
            response.setOperateTime(taskSDO.getAuditStartTime());
            response.setAuditOperateType(AuditOperateTypeEnum.START_UP.getType());
            response.setAuditOperateDesc(AuditOperateTypeEnum.START_UP.getDesc());
            recordResponses.add(response);
        }
        // 处理人
        if (StringUtils.isNotBlank(taskSDO.getPrincipal())) {
            response = new SalesPlanAuditRecordResponse();
            response.setOperatorName(operateNameMap.get(taskSDO.getPrincipal().replace(USER_PREFIX, "")));
            response.setOperateTime(taskSDO.getAuditFinishTime());
            if (SalePlanAuditStatusEnum.FINISHED.getCode().equals(taskSDO.getStatus())) {
                response.setAuditOperateType(AuditOperateTypeEnum.APPROVE.getType());
                response.setAuditOperateDesc(AuditOperateTypeEnum.APPROVE.getDesc());
            } else if (SalePlanAuditStatusEnum.REJECT.getCode().equals(taskSDO.getStatus())){
                response.setAuditOperateType(AuditOperateTypeEnum.REJECT.getType());
                response.setAuditOperateDesc(AuditOperateTypeEnum.REJECT.getDesc());
                response.setComment(auditSDO.getAuditReason());
            }
            recordResponses.add(response);
        }
        return recordResponses;
    }

    private Map<String, String> fetchOperatorName(List<SalesPlanAuditTaskSDO> salesPlanAuditTaskSDOList) {
        List<String> userIdList = Lists.newArrayList();
        salesPlanAuditTaskSDOList.forEach(salesPlanAuditTaskSDO -> {
            if (StringUtils.isNotBlank(salesPlanAuditTaskSDO.getAuditInitiatorId())) {
                userIdList.add(salesPlanAuditTaskSDO.getAuditInitiatorId().replace(USER_PREFIX, ""));
            }
            if (StringUtils.isNotBlank(salesPlanAuditTaskSDO.getPrincipal())) {
                userIdList.add(salesPlanAuditTaskSDO.getPrincipal().replace(USER_PREFIX, ""));
            }
        });
        List<EmployeeSDO> employeeSDOList = platformEnhanceRepository.getEmployeeList(userIdList);
        if (CollectionUtils.isEmpty(employeeSDOList)) {
            return Maps.newHashMap();
        }
        return employeeSDOList.stream().collect(Collectors.toMap(EmployeeSDO::getId, EmployeeSDO::getName));
    }

    private List<SalesPlanAuditTaskSDO> querySalesPlanAuditTaskList(List<String> auditOrderIdList) {
        SalesPlanAuditTaskQueryRequest taskQueryRequest = new SalesPlanAuditTaskQueryRequest();
        taskQueryRequest.setAuditOrderIdList(auditOrderIdList);
        taskQueryRequest.setLimit(100);
        taskQueryRequest.setStart(0);
        PageResult<List<SalesPlanAuditTaskSDO>> pageResult = salesPlanAuditTaskRepository.pageQuery(taskQueryRequest);
        if (null == pageResult || pageResult.getTotal() < 1) {
            return null;
        }
        return pageResult.getContent();
    }

    private List<SalesPlanAuditSDO> querySalesPlanAuditList(SalesPlanReportRequest request) {
        QuerySalesPlanAuditRequest auditRequest = new QuerySalesPlanAuditRequest();
        auditRequest.setReportOrderIdList(Lists.newArrayList(request.getReportOrderId()));
        return salesPlanAuditRepository.querySalesPlanAuditList(auditRequest);
    }

    private SalesPlanReportPageQueryRequest convertSalesPlanReportPageQueryRequest(SalesPlanReportQueryRequest source) {
        if (null == source) {
            return null;
        }
        SalesPlanReportPageQueryRequest target = new SalesPlanReportPageQueryRequest();
        target.setBizId(source.getBizId());
        target.setBizType(source.getBizType());
        target.setModelId(source.getModelId());
        target.setModelType(source.getModelType());
        target.setReportEmployeeId(source.getOperatorId());
        return target;
    }

    private boolean buildSalesPlanReportDimension(SalesPlanReportQueryRequest request, SalesPlanReportRequest salesPlanReportRequest) {
        Integer relationOrganizationType = salesPlanReportRequest.getRelationOrganizationType();
        // 1、业务员（业务员角色）
        if (salesPlanReportRequest.getIsSales()) {
            request.setBizType(SalesPlanReportBizTypeEnum.PROMOTER_REPORT.getCode());
            request.setBizId(salesPlanReportRequest.getOperatorId());
        } else if (OrganizationTypeEnum.SALES_DEPARTMENT.getCode().equals(relationOrganizationType)) {
            request.setBizType(SalesPlanReportBizTypeEnum.DEPARTMENT_REPORT.getCode());
            request.setBizId(salesPlanReportRequest.getRelationOrganizationId());
        }
        // 3、销售渠道（渠道经理角色）
        else if (OrganizationTypeEnum.SALES_CHANNEL.getCode().equals(relationOrganizationType)) {
            request.setBizType(SalesPlanReportBizTypeEnum.CHANNEL_REPORT.getCode());
            request.setBizId(salesPlanReportRequest.getRelationOrganizationId());
        }
        // 5、业务单元（调度员/总经理角色）
        else if (OrganizationTypeEnum.COMPANY.getCode().equals(relationOrganizationType)) {
            request.setBizType(SalesPlanReportBizTypeEnum.BUSINESS_DIMENSION_REPORT.getCode());
            request.setBizId(salesPlanReportRequest.getRelationOrganizationId());
        } else {
            return false;
        }
        return true;
    }

    private void buildReportQueryRequest(SalesPlanReportQueryRequest reportQueryRequest, SalesPlanReportRequest request) {
        reportQueryRequest.setModelId(request.getModelId());
        reportQueryRequest.setModelType(request.getModel());
    }

    private boolean fetchPreReportAuditStatus(SalesPlanReportQueryRequest reportQueryRequest,SalesPlanReportRequest salesPlanReportRequest) {
        List<SalesPlanReportSDO> exSalesPlanReportSDOs = Lists.newArrayList();
        if (!SalesPlanReportBizTypeEnum.PROMOTER_REPORT.getCode().equals(reportQueryRequest.getBizType())) {
            QuerySalesPlanReportRequest exQuerySalesPlanReportRequest = new QuerySalesPlanReportRequest();
            exQuerySalesPlanReportRequest.setModelId(reportQueryRequest.getModelId());
            exQuerySalesPlanReportRequest.setModel(reportQueryRequest.getModelType());
            exQuerySalesPlanReportRequest.setParentId(reportQueryRequest.getBizId());
            // 判断是否有未完成的子提报单
            exSalesPlanReportSDOs = salesPlanReportRepository.querySalesPlanReportList(exQuerySalesPlanReportRequest);
            if (CollectionUtils.isNotEmpty(exSalesPlanReportSDOs)) {
                // 判断子提审单是否都完成  通过认定为终态
                boolean flag = exSalesPlanReportSDOs.stream().anyMatch(s -> s.getAuditStatus() != SalesPlanReportAuditStatusEnum.APPROVED.getCode());
                // 前序未审核完成, 不能提交审批
                return !flag;
            } else {
                // 提报新接口开关，开关打开执行新接口代码
                if (SALES_PLAN_REPORT_SWITCH.equals(BcOtsConstants.SALES_PLAN_REPORT_SWITCH())) {
                    return checkFirstNode(salesPlanReportRequest);
                }
                // 无前序提报单，不能提交审批
                return false;
            }
        }
        // 业务员无提交审批操作
        return false;
    }

    /**
     *
     */
    private boolean checkFirstNode(SalesPlanReportRequest request) {
        try {
            List<AuditSetting> settingList = getAuditConfiguration(request);
            if (CollectionUtils.isEmpty(settingList)) {
                return false;
            }
            AuditSetting auditSetting = settingList.stream().filter(setting -> {
                return getAuditSettingDetailTop(setting, request.getRelationOrganizationType(), request.getRoleCodes());
            }).findFirst().orElse(null);
            return Objects.nonNull(auditSetting);
        } catch (Exception e) {
            log.error("检查第一节点异常:",  e);
            return false;
        }
    }

    /**
     * 判断提报人当前是否处于第一审批节点
     * @return boolean
     */
    private boolean getAuditSettingDetailTop(AuditSetting audit, Integer organizationType, List<String> roleCodes) {
        List<AuditSettingDetail> auditDetails = obtainAuditSettingDetail(audit);
        if (CollectionUtils.isEmpty(auditDetails)) {
            log.error("SalesPlanReportQueryServiceImpl.checkReportSetting当前审批主单id=" + audit.getId()+ "settingDetail=" + JSONObject.toJSONString(audit));
            throw new FacadeException(ErrorMessage.code("OTS-02-002-01-16-025"));
        }
        Map<String, AuditSettingDetail> detailMap = Maps.newHashMap();
        auditDetails.forEach(auditDetail -> {
            String type = auditDetail.getOrganizationType();
            String roleId = auditDetail.getRoleId();
            if (Objects.isNull(detailMap.get(type + roleId))) {
                detailMap.put(organizationType + roleId, auditDetail);
            }
        });
        String roleCode = roleCodes.stream().filter(code -> {
            AuditSettingDetail auditSettingDetail = detailMap.get(organizationType + getRoleSDOMap().get(code));
            if (!Objects.isNull(auditSettingDetail)) {
                return auditSettingDetail.getAuditSequence() == 1;
            }
            return false;
        }).findFirst().orElse(null);

        return StringUtils.isNotBlank(roleCode);
    }

    private Map<String, String> getRoleSDOMap() {
        Map<String, String> roleSDOMap = new HashMap<>();
        Result<List<RoleSDO>> result = bcOtsService.getAllRoles(GetAllRolesRequest.builder().belongOrganizationId("1").build());
        if (!result.isSuccess() || org.apache.commons.collections4.CollectionUtils.isEmpty(result.getResult())) {
            log.info("查询角色信息失败AuditSettingDetailService.convertResponseList");
        } else {
            roleSDOMap = result.getResult().stream().collect(Collectors.toMap(RoleSDO::getCode, RoleSDO::getId, (a, b) -> a));
        }
        return roleSDOMap;
    }

    /**
     * 通过审批主单id获取审批配置子单信息
     * @param request request
     * @return result
     */
    private List<AuditSettingDetail> obtainAuditSettingDetail(AuditSetting request) {
        Result<List<AuditSettingDetail>> result = auditSettingDetailService.loadList(buildAuditSettingDetailRequest(request));
        if (!result.isSuccess() || CollectionUtils.isEmpty(result.getResult())) {
            return Lists.newArrayList();
        }
        return result.getResult();
    }

    private AuditSettingDetailLoadListRequest buildAuditSettingDetailRequest(AuditSetting request) {
        AuditSettingDetailLoadListRequest detailRequest = new AuditSettingDetailLoadListRequest();
        detailRequest.setAuditSettingId(request.getId());
        detailRequest.setStatus(AuditSettingStatusEnum.ENABLE.getType());
        return detailRequest;
    }


    /**
     * 获取审批配置
     * @param request request
     */
    private List<AuditSetting> getAuditConfiguration(SalesPlanReportRequest request) {
        log.info("SalesPlanReportQueryServiceImpl.getAuditConfiguration.request=" + JSONObject.toJSONString(request));
        SalesPlanReportRequest salesPlanRequest = new SalesPlanReportRequest();
        BeanUtils.copyProperties(request, salesPlanRequest);
        // 当前为销售渠道，或销售单元可直接获取对应审批配置
        if (OrganizationTypeEnum.SALES_CHANNEL.getCode().equals(request.getRelationOrganizationType()) ||
                OrganizationTypeEnum.COMPANY.getCode().equals(request.getRelationOrganizationType())) {
            salesPlanRequest.setRelationOrganizationId(request.getRelationOrganizationId());
        } else if (OrganizationTypeEnum.SALES_DEPARTMENT.getCode().equals(request.getRelationOrganizationType())) {
            // 向上反查对应组织id
            OrganizationSDO organizationSDO = obtainUpOrganization(request.getRelationOrganizationId(), OrganizationTypeEnum.SALES_CHANNEL.getCode());
            salesPlanRequest.setRelationOrganizationId(organizationSDO.getId());
            salesPlanRequest.setRelationOrganizationType(OrganizationTypeEnum.SALES_CHANNEL.getCode());
        } else if (OrganizationTypeEnum.SALES_ORGANIZATION.getCode().equals(request.getRelationOrganizationType())) {
            // 向上反查对应组织id
            OrganizationSDO organizationSDO = obtainUpOrganization(request.getRelationOrganizationId(), OrganizationTypeEnum.COMPANY.getCode());
            salesPlanRequest.setRelationOrganizationId(organizationSDO.getId());
            salesPlanRequest.setRelationOrganizationType(OrganizationTypeEnum.COMPANY.getCode());
        } else  {
            throw new FacadeException(ErrorMessage.code("OTS-02-002-01-16-024"));
        }
        log.info("SalesPlanReportQueryServiceImpl.obtainAuditSetting.request={}", JSONObject.toJSONString(salesPlanRequest));
        List<AuditSetting> auditSettings = obtainAuditSetting(salesPlanRequest);
        if (CollectionUtils.isEmpty(auditSettings)) {
            return Lists.newArrayList();
        }
        return auditSettings;
    }

    /**
     * 获取当前审批人的上级组织
     * @return
     */
    private OrganizationSDO obtainUpOrganization(String relationOrganizationId, Integer upOrganizationType) {
        // 获取当前组织向上回溯指定类型组织列表
        List<OrganizationSDO> organizationSDOList = platformEnhanceRepository.getTopOrganizationList(convert(relationOrganizationId, upOrganizationType));
        if (CollectionUtils.isEmpty(organizationSDOList)) {
            throw new FacadeException(ErrorMessage.code("OTS-02-003-01-16-013"));
        }
        // 获取最后一个组织即可
        return organizationSDOList.get(organizationSDOList.size() - 1);
    }

    /**
     * 获取审批配置主单信息
     * @param request request
     * @return result
     */
    private List<AuditSetting> obtainAuditSetting(SalesPlanReportRequest request) {
        // 获取审批配置主单、可能有多个
        Result<List<AuditSetting>> result = auditSettingService.loadList(buildAuditSettingRequest(request));
        if (!result.isSuccess() || CollectionUtils.isEmpty(result.getResult())) {
            return Lists.newArrayList();
        }
        return result.getResult();
    }

    private OrganizationListQueryRequest convert(String organizationId, Integer bizType) {
        OrganizationListQueryRequest topOrganizationListRequest = new OrganizationListQueryRequest();
        topOrganizationListRequest.setId(organizationId);
        topOrganizationListRequest.setType(bizType);
        return topOrganizationListRequest;
    }

    private AuditSettingLoadListRequest buildAuditSettingRequest(SalesPlanReportRequest request) {
        AuditSettingLoadListRequest auditSettingRequest = new AuditSettingLoadListRequest();
        auditSettingRequest.setStatus(AuditSettingStatusEnum.ENABLE.getType());
        if (SalesPlanModelEnum.PLAN_MODEL.getModel().equals(request.getModel())) {
            auditSettingRequest.setType(AuditSettingTypeEnum.SALES_PLAN_REPORT.getType());
        } else if (SalesPlanModelEnum.ADJUST_MODEL.getModel().equals(request.getModel())) {
            auditSettingRequest.setType(AuditSettingTypeEnum.SALES_PLAN_ADJUST.getType());
        }
        if (OrganizationTypeEnum.SALES_DEPARTMENT.getCode().equals(request.getRelationOrganizationType()) ||
                OrganizationTypeEnum.SALES_CHANNEL.getCode().equals(request.getRelationOrganizationType())) {
            auditSettingRequest.setOrgChannelCode(request.getRelationOrganizationId());
        } else if (OrganizationTypeEnum.SALES_ORGANIZATION.getCode().equals(request.getRelationOrganizationType()) ||
                OrganizationTypeEnum.COMPANY.getCode().equals(request.getRelationOrganizationType())) {
            auditSettingRequest.setOrgBusinessUnitCode(request.getRelationOrganizationId());
        }
        log.info("SalesPlanReportQueryServiceImpl.buildAuditSettingRequest.request={}", JSONObject.toJSONString(auditSettingRequest));
        return auditSettingRequest;
    }
}
